﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using MineDiscover.Interfaces;
using MineDiscover.Utils;
using System.Threading;

namespace MineDiscover
{
    public class MapPainter
    {
        private MapMine mapMine;
        private ITileStyle[,] tileStyles;
        private SizeF sizeSquare;
        private int columnsMap;
        private int rowsMap;
        private Control control;
        private Point positionMouse;

        public MapPainter()
            : this(new MapMine(), new Control())
        { }

        public MapPainter(MapMine mapMine, Control control)
        {
            this.mapMine = mapMine;
            this.control = control;

            columnsMap = GameMineDiscover.GetInstance().Difficulty.Columns;
            rowsMap = GameMineDiscover.GetInstance().Difficulty.Rows;

            tileStyles = new ITileStyle[columnsMap, rowsMap];
        }

        public void CreateVsPaint()
        {
            this.control.Margin = new Padding(0);
            
            Graphics gp = control.CreateGraphics();
            gp.Clear(Color.Beige);

            sizeSquare = new SizeF((float)control.Width / (float)columnsMap, (float)control.Height / (float)rowsMap);

            for (int i = 0; i < columnsMap; i++)
            {
                for (int j = 0; j < rowsMap; j++)
                {
                    ITileStyle tileStyle = tileStyles[i, j] = TileFactory.GetInstance().GetTileStyle(TileStyle.TileDraw);
                    // Initalize TileDraw
                    tileStyle.CreateTilePaint(control.CreateGraphics(), new PointF(i * sizeSquare.Width, j * sizeSquare.Height), sizeSquare, 16);
                    tileStyle.Tile = GameMineDiscover.GetInstance().MapMine.Tiles[i, j];
                    tileStyle.OnPaint();
                }
            }
        }

        private Position GetTileMouseOver()
        {
            int x = (int)(positionMouse.X / sizeSquare.Width);
            int y = (int)(positionMouse.Y / sizeSquare.Height);
            return new Position(x, y);
        }

        public void MouseOverMap(Point pointMouse)
        {
            this.positionMouse = pointMouse;

            ////Position position = GetTileMouseOver();
            
            ////if (Helper.ValidateOverBoundary(position.X, position.Y, rowsMap, columnsMap))
            ////{
            ////    tileStyles[position.X, position.Y].OnMouseOver();
            ////}
        }

        public void OnRightClick()
        {
            Position position = GetTileMouseOver();
            
            if (Helper.ValidateOverBoundary(position.X, position.Y, rowsMap, columnsMap))
            {
                mapMine.TileRightClick(tileStyles[position.X, position.Y].Tile);
                tileStyles[position.X, position.Y].OnMouseRightClick();
            }
        }

        public void OnLeftClick()
        {
            Position position = GetTileMouseOver();

            if (Helper.ValidateOverBoundary(position.X, position.Y, rowsMap, columnsMap))
            {
                mapMine.TileLeftClick(tileStyles[position.X, position.Y].Tile);
            }

            for (int i = 0; i < columnsMap; i++)
            {
                for (int j = 0; j < rowsMap; j++)
                {
                    ITileStyle tileStyle = tileStyles[i, j];
                    tileStyle.OnMouseLeftClick();
                }
            }
        }

        public void EndGame()
        {
            Position position = GetTileMouseOver();
            tileStyles[position.X, position.Y].OnExplode();
            OpenMine();
        }

        private void OpenMine()
        {
            Position position = GetTileMouseOver();
            for (int i = 0; i < columnsMap; i++)
            {
                for (int j = 0; j < rowsMap; j++)
                {
                    ITileStyle tileStyle = tileStyles[i, j];
                    if (tileStyle.Tile.IsMine && !tileStyle.Tile.positionInMap.Equals(position))
                    {
                        tileStyle.OnOpenMine();
                        Thread.Sleep(200);
                    }
                }
            }
        }

        public void WinGame()
        {
            OpenMine();
        }
    }
}
